#include "game.h"
#include "../utils/axios.h"
#include "../utils/vec.h"
#include "auth.h"

gameStatus_t curr_gameStatus;

// typedef enum {
// 	GAME_STATUS_INIT,
// 	GAME_STATUS_START,
//     GAME_STATUS_CALLLOAD,
//     GAME_STATUS_ROBLOAD,
// 	GAME_STATUS_GAMEING,
// 	GAME_STATUS_END,
// 	GAME_STATUS_WAIT_PLAYER,
// } GAME_STATUS;
const char *game_status[7] = {"init",   "start", "call",   "rob",
                              "gaming", "end",   "waiting"};

/**
 * typedef struct {
    int id;
    char* room_name;
    GAME_STATUS status;
    player_t players[3];
    int player_count;
    int who;
    int who_load;
    short rob_status[3];
    int count;
    Vec(CARD) handcard;
    Vec(CARD) cards;
} gameStatus_t; // 游戏信息
 */
void gameStatus_from_json(cJSON *body) {
    //log_debug("%s",cJSON_Print(body));
    gameStatus_t *game = &curr_gameStatus;
    game->id = cJSON_GetObjectItem(body, "id")->valueint;
    game->room_name = strdup(cJSON_GetObjectItem(body, "room_name")->valuestring);
    game->status = (GAME_STATUS)cJSON_GetObjectItem(body, "status")->valueint;
    game->player_count = cJSON_GetObjectItem(body, "player_count")->valueint;
    game->who = cJSON_GetObjectItem(body, "who")->valueint;
    game->who_load = cJSON_GetObjectItem(body, "who_load")->valueint;
    cJSON *players_json = cJSON_GetObjectItem(body, "players");
    for (int i = 0; i < 3; i++) {
        cJSON *player_json = cJSON_GetArrayItem(players_json, i);
        int id = cJSON_GetObjectItem(player_json, "id")->valueint;
        game->players[i].id = id;
        if (id != -1) {
            game->players[i].username =
                strdup(cJSON_GetObjectItem(player_json, "username")->valuestring);
            game->players[i].cardsize =
                cJSON_GetObjectItem(player_json, "cardsize")->valueint;
            game->players[i].status = 
                cJSON_GetObjectItem(player_json, "status")->valueint;
        }
    }
    cJSON *rob_status_json = cJSON_GetObjectItem(body, "rob_status");
    for (int i = 0; i < 3; i++) {
        game->rob_status[i] = cJSON_GetArrayItem(rob_status_json, i)->valueint;
    }
    game->count = cJSON_GetObjectItem(body, "count")->valueint;
    vec_free(&game->cards);
    vec_free(&game->handcard);
    vec_init(&game->cards, 0, 10);
    vec_init(&game->handcard, 0, 10);
    cJSON *handcard_json = cJSON_GetObjectItem(body, "handcard");
    for (int i = 0; i < cJSON_GetArraySize(handcard_json); i++) {
        vec_append(&game->handcard,
                   cJSON_GetArrayItem(handcard_json, i)->valueint);
    }
    cJSON *cards_json = cJSON_GetObjectItem(body, "cards");
    for (int i = 0; i < cJSON_GetArraySize(cards_json); i++) {
        vec_append(&game->cards, cJSON_GetArrayItem(cards_json, i)->valueint);
    }
    return;
}

void get_gameStatus(int game_id) {
    // 传送游戏id
    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "user_id", current_user.id);
    cJSON_AddStringToObject(root, "username", current_user.username);
    cJSON_AddNumberToObject(root, "game_id", game_id);
    // log_info("get_gameStatus: %d", game_id);
    // 发送请求
    response_t *response = request(MEVEN_HTTP_GET, "/game/status", NULL, root);
    if (response == NULL) {
        return;
    }
    if (response->code != RESPONSE_OK) {
        log_error("get_gameStatus: %d %s", response->code, response->message);
        response_free(response);
        return;
    }
    // 解析JSON
    gameStatus_from_json(response->body);
    response_free(response);
    // log_info("get gameStatus success");
    return;
}

// typedef struct {
//     int id;
//     char* room_name;
//     int player_count;
//     GAME_STATUS status;
// } room;
room_list *get_room_list() {
    response_t *response =
        request(MEVEN_HTTP_GET, "/game/room_list", NULL, NULL);
    if (response == NULL) {
        log_error("get_room_list: request failed");
        return NULL;
    }
    if (response->code != RESPONSE_OK) {
        log_error("get_gamelist: %d %s", response->code, response->message);
        return NULL;
    }
    // 解析JSON
    room_list *roomList = malloc(sizeof(roomList));
    vec_init(roomList, 0, 3);
    cJSON *body = response->body;
    log_info("list");
    for (int i = 0; i < cJSON_GetArraySize(body); i++) {
        cJSON *room_json = cJSON_GetArrayItem(body, i);
        room *room = malloc(sizeof(room));
        room->id = cJSON_GetObjectItem(room_json, "game_id")->valueint;
        room->room_name =
            cJSON_GetObjectItem(room_json, "room_name")->valuestring;
        room->player_count =
            cJSON_GetObjectItem(room_json, "player_count")->valueint;
        room->status = cJSON_GetObjectItem(room_json, "status")->valueint;
        vec_append(roomList, *room);
    }
    
    return roomList;
}

response_t* set_player_status(PLAYER_STATUS status) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "user_id", current_user.id);
    cJSON_AddNumberToObject(root, "game_id", curr_gameStatus.id);
    cJSON_AddStringToObject(root, "username", current_user.username);
    cJSON_AddNumberToObject(root, "status", status);

    response_t * resp = request(MEVEN_HTTP_POST, "/game/setStatus", NULL, root);
    cJSON_Delete(root);
    return resp;
}

response_t* join_room(int game_id) {
    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "user_id", current_user.id);
    cJSON_AddNumberToObject(root, "game_id", game_id);
    cJSON_AddStringToObject(root, "username", current_user.username);

    response_t * resp = request(MEVEN_HTTP_POST, "/game/join_room", NULL, root);
    cJSON_Delete(root);
    return resp;
}

void gameStatus_destory(gameStatus_t* gameStatus) {
    free(gameStatus->room_name);
    vec_free(&gameStatus->cards);
    vec_free(&gameStatus->handcard);
    free(gameStatus);
}

void free_gameStatus(gameStatus_t* gameStatus) {
    vec_free(&gameStatus->cards);
    vec_free(&gameStatus->handcard);
    free(gameStatus->room_name);
    free(gameStatus);
}